﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
using Microsoft.Xna.Framework.Content;
using Brain.Skinning;
using Microsoft.Xna.Framework;

namespace Brain_Skinning
{
    public class SkinnedModelContent
    {
        [ContentSerializer(ElementName = "Model")]
        public ModelContent Model { get; protected set; }

        [ContentSerializer(ElementName = "AnimationClips")]
        public Dictionary<string, SkinnedAnimationClip> AnimationClips { get; protected set; }

        [ContentSerializer(ElementName = "SkinnedBones")]
        public SkinnedBone[] SkinnedBones { get; protected set; }

        [ContentSerializer(ElementName = "BindPoses")]
        public Matrix[] BindPoses { get; set; }

        internal SkinnedModelContent(ModelContent m, SkinnedBone[] bones,
            Dictionary<string, SkinnedAnimationClip> clips)
        {
            Model = m;
            this.SkinnedBones = bones;
            this.AnimationClips = clips;
        }

        internal void Write(ContentWriter output)
        {
            output.WriteObject<ModelContent>(Model);

            output.Write(SkinnedBones.Length);
            foreach (SkinnedBone bone in SkinnedBones)
            {
                output.Write(bone.InverseBindPose);
                output.Write(bone.ParentBone);
                output.Write(bone.Name);
            }

            if (AnimationClips != null)
            {
                output.Write(AnimationClips.Count);
                foreach (KeyValuePair<string, SkinnedAnimationClip> clip in AnimationClips)
                {
                    output.Write(clip.Key);
                    output.Write(clip.Value.Duration);

                    output.Write(clip.Value.Bones.Count);
                    foreach (BoneKeyFrameCollection frameCol in clip.Value.Bones.Values)
                    {
                        output.Write(frameCol.BoneIndex);

                        output.Write(frameCol.KeyFrames.Length);
                        foreach (Frame_Skinned frame in frameCol.KeyFrames)
                        {
                            output.Write(frame.Time);
                            output.Write(frame.Position);
                            output.Write(frame.Orientation);
                            output.Write(frame.Scale);
                        }
                    }
                }
            }
            else
            {
                output.Write(0);
            }

            output.Write(BindPoses.Length);
            foreach (Matrix mat in BindPoses)
            {
                output.Write(mat);
            }
        }
    }
}
